﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Threading;

namespace Kevin.SLUserControlLibrary
{
    public class SelectToggleButton : ButtonBase
    {

        #region DependencyProperty

        public static readonly DependencyProperty LeftContentProperty = DependencyProperty.Register("LeftContent", typeof(string), typeof(SelectToggleButton), null);
        public static readonly DependencyProperty RightContentProperty = DependencyProperty.Register("RightContent", typeof(string), typeof(SelectToggleButton), null);
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(SelectToggleButton), null);
        public static readonly DependencyProperty ContentWidthProperty = DependencyProperty.Register("ContentWidth", typeof(double), typeof(SelectToggleButton), null);
        public static readonly DependencyProperty IsContentEnableProperty = DependencyProperty.Register("IsContentEnable", typeof(bool), typeof(SelectToggleButton),
            new PropertyMetadata(true, (new PropertyChangedCallback(OnIsContentEnablePropertyChanged))));

        #endregion

        #region Property

        public string LeftContent
        {
            get { return (string)this.GetValue(SelectToggleButton.LeftContentProperty); }
            set { this.SetValue(SelectToggleButton.LeftContentProperty, value); }
        }

        public string RightContent
        {
            get { return (string)this.GetValue(SelectToggleButton.RightContentProperty); }
            set { this.SetValue(SelectToggleButton.RightContentProperty, value); }
        }

        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)this.GetValue(SelectToggleButton.CornerRadiusProperty); }
            set { this.SetValue(SelectToggleButton.CornerRadiusProperty, value); }
        }

        public double ContentWidth
        {
            get { return (double)this.GetValue(SelectToggleButton.ContentWidthProperty); }
            set
            {
                this.SetValue(SelectToggleButton.ContentWidthProperty, value);
                this.SetValue(SelectToggleButton.WidthProperty, value * 2);
            }
        }

        public bool IsContentEnable
        {
            get { return (bool)this.GetValue(SelectToggleButton.IsContentEnableProperty); }
            set
            {
                base.IsEnabled = value;
                this.SetValue(SelectToggleButton.IsContentEnableProperty, value);
            }
        }

        #endregion

        #region Constant
        private const string LeftSelectState = "LeftSelectState";
        private const string RightSelectState = "RightSelectState";
        #endregion

        #region Field
        private Border bdLeftContent;
        private Border bdRightContent;

        private bool isLeftSelected = true;

        #endregion

        #region Event

        public event RoutedEventHandler LeftButtonClick;
        public event RoutedEventHandler RightButtonClick;

        #endregion

        #region Constructor

        public SelectToggleButton()
            : base()
        {
            this.DefaultStyleKey = typeof(SelectToggleButton);
        }

        #endregion

        #region Template

        public override void OnApplyTemplate()
        {
            this.bdLeftContent = (Border)this.GetTemplateChild("bdLeftContent");
            this.bdRightContent = (Border)this.GetTemplateChild("bdRightContent");

            this.bdLeftContent.MouseLeftButtonDown += new MouseButtonEventHandler(bdLeftContent_MouseLeftButtonDown);
            this.bdRightContent.MouseLeftButtonDown += new MouseButtonEventHandler(bdRightContent_MouseLeftButtonDown);

            this.ChangeVisualState(false);
        }

        #endregion

        #region Mouse Event

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            this.ChangeVisualState(true);
        }

        protected override void OnClick()
        {
            if (isLeftSelected)
            {
                VisualStateManager.GoToState(this, RightSelectState, true);
                isLeftSelected = false;

                if (this.RightButtonClick != null)
                {
                    this.RightButtonClick(this, new RoutedEventArgs());
                }
            }
            else
            {
                VisualStateManager.GoToState(this, LeftSelectState, true);
                isLeftSelected = true;

                if (this.LeftButtonClick != null)
                {
                    this.LeftButtonClick(this, new RoutedEventArgs());
                }
            }
        }

        protected override void OnIsPressedChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnIsPressedChanged(e);
            this.ChangeVisualState(true);
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            this.ChangeVisualState(true);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);
            this.ChangeVisualState(true);
        }

        protected override void OnLostFocus(RoutedEventArgs e)
        {
            base.OnLostFocus(e);
            this.ChangeVisualState(true);
        }

        protected override void OnLostMouseCapture(MouseEventArgs e)
        {
            base.OnLostMouseCapture(e);
            this.ChangeVisualState(true);
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            base.OnMouseEnter(e);
            this.ChangeVisualState(true);
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            base.OnMouseLeave(e);
            this.ChangeVisualState(true);
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            this.ChangeVisualState(true);
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);
            this.ChangeVisualState(true);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            this.ChangeVisualState(true);
        }

        private void bdRightContent_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (isLeftSelected == false)
            {
                e.Handled = true;
            }
        }

        private void bdLeftContent_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (isLeftSelected == true)
            {
                e.Handled = true;
            }
        }

        #endregion

        #region VisualState

        private void ChangeVisualState(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateManager.GoToState(this, "Disabled", useTransitions);
            }
            else if (base.IsPressed)
            {
                VisualStateManager.GoToState(this, "Pressed", useTransitions);
            }
            else if (base.IsMouseOver)
            {
                VisualStateManager.GoToState(this, "MouseOver", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "Normal", useTransitions);
            }

            if (base.IsFocused && base.IsEnabled)
            {
                VisualStateManager.GoToState(this, "Focused", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "Unfocused", useTransitions);
            }
        }

        #endregion

        #region CallBack Methods
        private static void OnIsContentEnablePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SelectToggleButton)d).ChangeVisualState(true);
        }

        #endregion
    }
}
